﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Eb;

namespace Es
{
    public class ServerNodeInfo
    {
        public string node_type;
        public uint node_id;
        public string node_mq;
        public string ip;
    }

    public class DefCluster : ComponentDef
    {
        //---------------------------------------------------------------------
        public override void defAllProp(Dictionary<string, string> map_param)
        {
        }
    }

    public class ServerCluster<TDef> : Component<TDef> where TDef : DefCluster, new()
    {
        //-------------------------------------------------------------------------
        // key1=node_type, key2=node_mq
        Dictionary<string, Dictionary<string, ServerNodeInfo>> mMapServerNodeInfo
            = new Dictionary<string, Dictionary<string, ServerNodeInfo>>();

        //-------------------------------------------------------------------------
        //public IZkClient ZkClient { get; private set; }

        //-------------------------------------------------------------------------
        public override void init()
        {
            EbLog.Note("ServerCluster.init()");

            var cfg = EsEngine.Instance.Config;
            var settings = EsEngine.Instance.Settings;

            // 创建Zk节点
            //string server_string = cfg.ZkClientIp + ":" + cfg.ZkClientPort;
            //ZkClient = new ZkClient(server_string, settings.Log4NetConfigZk);
            //EsEngine.Instance.ZkClient = ZkClient;
            //EsEngine.Instance.NodeId = _createZkNode();

            //// 队列名=ProjectName_Version_NodeType_NodeId
            //EsEngine.Instance.NodeMQ = settings.ProjectName + "_" + cfg.Version
            //    + "_" + settings.NodeTypeString + "_" + EsEngine.Instance.NodeId;

            //var mq = (EsEngineRabbitMQ)EsEngine.Instance.RpcCallerMQ;
            //mq.createNodeMQ();

            //// 监控本项目进程列表根节点
            //string zkpath_project = "/" + settings.ProjectName + "/" + cfg.Version;
            //EsEngine.Instance.ZkClient.subscribeChildChanges(zkpath_project, _onSubscribeChildChanges);
        }

        //-------------------------------------------------------------------------
        public override void release()
        {
            //if (ZkClient != null)
            //{
            //    ZkClient.close();
            //    ZkClient = null;
            //}

            EbLog.Note("ServerCluster.release()");
        }

        //-------------------------------------------------------------------------
        public override void update(float elapsed_tm)
        {
            //if (ZkClient != null)
            //{
            //    ZkClient.update();
            //}
        }

        //-------------------------------------------------------------------------
        public override void handleEvent(object sender, EntityEvent e)
        {
        }

        //---------------------------------------------------------------------
        public Dictionary<string, ServerNodeInfo> getMapServerNode(string node_type)
        {
            Dictionary<string, ServerNodeInfo> m = null;
            mMapServerNodeInfo.TryGetValue(node_type, out m);
            return m;
        }

        //-------------------------------------------------------------------------
        public ServerNodeInfo randomGetNode(string node_type)
        {
            var m = getMapServerNode(node_type);
            if (m == null) return null;

            List<string> list_nodemq = new List<string>(m.Keys);

            string nodemq = "";
            if (list_nodemq.Count > 0)
            {
                Random rd = new Random();
                int index = rd.Next(0, list_nodemq.Count);
                nodemq = list_nodemq[index];
            }

            if (!string.IsNullOrEmpty(nodemq))
            {
                return m[nodemq];
            }

            return null;
        }

        //---------------------------------------------------------------------
        //uint _createZkNode()
        //{
        //    var cfg = EsEngine.Instance.Config;
        //    var settings = EsEngine.Instance.Settings;

        //    string zk_parent_path = "/" + settings.ProjectName + "/" + cfg.Version + "/";

        //    // 检查并创建父节点
        //    string[] list_node = zk_parent_path.Split('/');
        //    string zk_path = "";
        //    foreach (var i in list_node)
        //    {
        //        if (string.IsNullOrEmpty(i)) continue;

        //        zk_path += "/";
        //        zk_path += i;

        //        if (!ZkClient.syncExists(zk_path, false))
        //        {
        //            ZkClient.syncCreate(zk_path, "", ZK_CONST.ZOO_DEFAULT_NODE);
        //        }
        //    }

        //    // 创建子节点
        //    zk_path += "/" + settings.NodeTypeString + "_" + settings.NodeIp + "_";
        //    zk_path = ZkClient.syncCreate(zk_path, "", ZK_CONST.ZOO_EPHEMERAL | ZK_CONST.ZOO_SEQUENCE);

        //    // 返回NodeId
        //    string last_str = zk_path.Substring(zk_path.LastIndexOf('/') + 1);
        //    char[] char_separators = new char[] { '_' };
        //    string[] list_str = last_str.Split(char_separators);
        //    return uint.Parse(list_str[2]);
        //}

        ////-------------------------------------------------------------------------
        //void _onSubscribeChildChanges(int result, string data, string[] chdn, Dictionary<string, object> param)
        //{
        //    EbLog.Note("ServerCluster._onSubscribeChildChanges()");

        //    if (result != 0)
        //    {
        //        EbLog.Error("Error result=" + result);
        //        return;
        //    }

        //    var cfg = EsEngine.Instance.Config;
        //    var settings = EsEngine.Instance.Settings;
        //    string[] list_str;
        //    char[] char_separators = new char[] { '_' };
        //    if (chdn == null) chdn = new string[] { };

        //    foreach (var i in chdn)
        //    {
        //        list_str = i.Split(char_separators);
        //        if (list_str.Length != 3) continue;

        //        ServerNodeInfo info = new ServerNodeInfo();
        //        info.node_type = list_str[0];
        //        info.node_id = uint.Parse(list_str[2]);
        //        info.node_mq = settings.ProjectName + "_" + cfg.Version + "_" + info.node_type + "_" + info.node_id.ToString();
        //        info.ip = list_str[1];

        //        EbLog.Note("ServerCluster: node_type=" + info.node_type + " node_mq=" + info.node_mq + " ip=" + info.ip);

        //        Dictionary<string, ServerNodeInfo> m = null;
        //        mMapServerNodeInfo.TryGetValue(info.node_type, out m);
        //        if (m == null)
        //        {
        //            m = new Dictionary<string, ServerNodeInfo>();
        //            m[info.node_mq] = info;
        //            mMapServerNodeInfo[info.node_type] = m;
        //        }
        //        else
        //        {
        //            m[info.node_mq] = info;
        //        }
        //    }
        //}
    }
}
